<template>
  <div class="image-compress">
    <header class="header">
      <div class="header-content">
        <router-link to="/" class="back-button">
          <el-button icon="el-icon-back">返回首页</el-button>
        </router-link>
        <div class="title-container">
          <h1>图片压缩工具</h1>
          <p class="subtitle">快速高效的图片压缩服务，支持多种格式</p>
        </div>
      </div>
    </header>

    <el-card class="compress-card">
      <el-upload
        class="upload-area"
        drag
        :auto-upload="false"
        :show-file-list="true"
        :multiple="false"
        :headers="headers"
        name="image"
        accept="image/*"
        ref="uploadRef"
        @change="handleFileChange"
      >
        <div class="upload-content">
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="upload-text">
            <h3>点击或拖拽图片到此处</h3>
            <p>支持 JPG、PNG、WebP 等格式</p>
          </div>
        </div>
      </el-upload>

      <div class="compress-options" v-if="selectedFile">
        <div class="quality-options">
          <h3>压缩质量：</h3>
          <el-radio-group v-model="quality" size="large">
            <el-radio-button :label="30">低</el-radio-button>
            <el-radio-button :label="60">中</el-radio-button>
            <el-radio-button :label="80">高</el-radio-button>
          </el-radio-group>
        </div>
        
        <div class="custom-quality">
          <span>自定义质量：</span>
          <el-slider
            v-model="quality"
            :min="1"
            :max="100"
            :step="1"
            show-input
            :show-input-controls="true"
            style="width: 300px"
          />
        </div>

        <el-button 
          type="primary" 
          size="large" 
          class="compress-button"
          :loading="compressing"
          @click="startCompress"
        >
          开始压缩
        </el-button>
      </div>
    </el-card>

    <el-card v-if="showPreview" class="preview-card">
      <div class="preview-container">
        <div class="preview-item">
          <h4>原图</h4>
          <img :src="originalImage" alt="原图" />
          <div class="image-info">
            <p>大小：{{ formatFileSize(originalSize) }}</p>
            <p>格式：{{ originalFormat }}</p>
          </div>
        </div>
        <div class="preview-item">
          <h4>压缩后</h4>
          <img :src="compressedImage" alt="压缩后" v-if="compressedImage" />
          <div class="image-info" v-if="compressedImage">
            <p>大小：{{ formatFileSize(compressedSize) }}</p>
            <p>压缩率：{{ compressionRatio }}%</p>
            <el-button type="primary" @click="downloadImage">下载图片</el-button>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { UploadFilled } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'

const router = useRouter()
const uploadRef = ref()
const selectedFile = ref<File | null>(null)
const uploadUrl = '/api/image/compress'
const headers = {
  Accept: 'application/json'
}
const quality = ref(80)
const originalImage = ref('')
const compressedImage = ref('')
const showPreview = ref(false)
const compressing = ref(false)
const originalSize = ref(0)
const compressedSize = ref(0)
const originalFormat = ref('')

const compressionRatio = computed(() => {
  if (originalSize.value === 0) return 0
  const ratio = ((originalSize.value - compressedSize.value) / originalSize.value) * 100
  return Math.round(ratio)
})

const formatFileSize = (bytes: number) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const handleFileChange = (file: any) => {
  const isImage = file.raw.type.startsWith('image/')
  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }

  const maxSize = 10 * 1024 * 1024 // 10MB
  if (file.raw.size > maxSize) {
    ElMessage.error('图片大小不能超过10MB!')
    return false
  }

  selectedFile.value = file.raw
  originalSize.value = file.raw.size
  originalFormat.value = file.raw.type.split('/')[1].toUpperCase()
  
  // 创建预览URL
  const reader = new FileReader()
  reader.onload = (e) => {
    originalImage.value = e.target?.result as string
    showPreview.value = true
  }
  reader.readAsDataURL(file.raw)
}

const startCompress = async () => {
  if (!selectedFile.value) {
    ElMessage.warning('请先选择要压缩的图片')
    return
  }

  compressing.value = true
  const formData = new FormData()
  formData.append('image', selectedFile.value)
  formData.append('quality', quality.value.toString())
  
  try {
    const response = await fetch('/api/image/compress', {
      method: 'POST',
      headers: {
        Accept: 'application/json'
      },
      body: formData
    })
    
    if (!response.ok) {
      const errorData = await response.json()
      throw new Error(errorData.error || '压缩失败')
    }
    
    const data = await response.json()
    if (data.success) {
      compressedImage.value = `/api/image/download/${data.filename}`
      compressedSize.value = data.size
      ElMessage.success('图片压缩成功')
    } else {
      throw new Error(data.error || '压缩失败')
    }
  } catch (error: any) {
    ElMessage.error(error.message || '图片压缩失败')
    console.error('压缩错误:', error)
  } finally {
    compressing.value = false
  }
}

const handleSuccess = (response: any) => {
  if (!response.success) {
    ElMessage.error(response.error || '图片压缩失败')
    return
  }
  compressedImage.value = `/api/image/download/${response.filename}`
  compressedSize.value = response.size
  ElMessage.success('图片压缩成功')
}

const handleError = (error: any) => {
  let errorMessage = '图片压缩失败'
  if (error.response) {
    try {
      const response = JSON.parse(error.response)
      errorMessage = response.error || errorMessage
    } catch (e) {
      console.error('解析错误响应失败:', e)
    }
  }
  ElMessage.error(errorMessage)
  compressing.value = false
}

const handleProgress = (event: any) => {
  compressing.value = true
}

const downloadImage = async () => {
  try {
    const response = await fetch(compressedImage.value)
    const blob = await response.blob()
    const url = window.URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `compressed_${Date.now()}.${originalFormat.value.toLowerCase()}`
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    window.URL.revokeObjectURL(url)
  } catch (error) {
    ElMessage.error('下载失败')
  }
}
</script>

<style scoped>
.image-compress {
  padding: 2rem;
  max-width: 1200px;
  margin: 0 auto;
}

.header {
  text-align: center;
  margin-bottom: 3rem;
}

.header-content {
  display: flex;
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 2rem;
  position: relative;
}

.back-button {
  position: absolute;
  left: 2rem;
  text-decoration: none;
}

.title-container {
  flex: 1;
  text-align: center;
}

.header h1 {
  color: #303133;
  font-size: 2.5rem;
  margin-bottom: 1rem;
}

.subtitle {
  color: #606266;
  font-size: 1.2rem;
}

.compress-card {
  background: #fff;
  border-radius: 8px;
  padding: 2rem;
  margin-bottom: 2rem;
}

.upload-area {
  border: 2px dashed #e4e7ed;
  border-radius: 8px;
  padding: 2rem;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.3s;
}

.upload-area:hover {
  border-color: #409EFF;
}

.upload-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.el-icon--upload {
  font-size: 4rem;
  color: #409EFF;
}

.upload-text h3 {
  font-size: 1.5rem;
  color: #303133;
  margin-bottom: 0.5rem;
}

.upload-text p {
  color: #909399;
}

.compress-options {
  margin-top: 2rem;
  text-align: center;
}

.quality-options {
  margin-bottom: 2rem;
}

.quality-options h3 {
  margin-bottom: 1rem;
  color: #303133;
}

.custom-quality {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-bottom: 2rem;
}

.compress-button {
  width: 200px;
  height: 50px;
  font-size: 1.2rem;
}

.preview-card {
  margin-top: 2rem;
}

.preview-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  padding: 1rem;
}

.preview-item {
  text-align: center;
}

.preview-item h4 {
  font-size: 1.2rem;
  color: #303133;
  margin-bottom: 1rem;
}

.preview-item img {
  max-width: 100%;
  max-height: 400px;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.image-info {
  margin-top: 1rem;
  color: #606266;
}

.image-info p {
  margin: 0.5rem 0;
}
</style> 